package org.gthelper.handler;

import java.awt.image.RenderedImage;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.UUID;

import org.apache.hadoop.io.Text;
import org.geotools.coverage.grid.GridCoverage2D;
import org.gthelper.data.DataGeter;
import org.gthelper.database.FileInfo;
import org.gthelper.database.FileStatus;
import org.gthelper.error.ErrorCode;
import org.gthelper.hdfs.HdfsMA;
import org.gthelper.hdpWritable.HdpRenderedImageWritable;
import org.gthelper.imageProcess.geotiffTreater;
import org.gthelper.order.OrderInfo;
import org.gthelper.server.SysInfo;
import org.opengis.geometry.Envelope;

/**
 * 上传文件
 * @author pig
 * 验证文件存在\00\00->
 * 接收和缓存文\00\00->
 * 读取文件与切\00\00->
 * 构建hdfs文件\00\00->
 * 存储分块文件->
 * 更新文件信息
 */
public class Upload extends Handler
{

	@Override
	public int handle(OrderInfo orderinfo) {
		// TODO 自动生成的方法存\00\00
		//getid
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		DataGeter dg = new DataGeter();
		int errcode=dg.getData(orderinfo.orderStream, baos);
		if(errcode!=ErrorCode.NORMAL)return errcode;
		byte[] userid = baos.toByteArray();
		baos.reset();
		
		//--------------------------------------------------------------------get filename
		errcode = dg.getData(orderinfo.orderStream, baos);
		if(errcode!=ErrorCode.NORMAL)return errcode;
		byte[] filename = baos.toByteArray();
		baos.reset();
		
		//--------------------------------------------------------------------to String
		String usrid="";
		String fileName="";
		try {
			usrid = new String(userid,"UTF-8");
			fileName = new String(filename,"UTF-8");
		} catch (UnsupportedEncodingException e) {
			// TODO 自动生成\00\00 catch \00\00
			e.printStackTrace();
			try {
				orderinfo.mainInput.close();
			} catch (IOException e1) {
				// TODO 自动生成\00\00 catch \00\00
				e1.printStackTrace();
			}
			return ErrorCode.UNKNOWN;
		}
		
		if((fileName.indexOf('/'))>-1)return ErrorCode.WRONGNAME;
		if((fileName.indexOf('\\'))>-1)return ErrorCode.WRONGNAME;
		
		//--------------------------------------------------------------------check
		FileInfo fileinfo=null;
		try {
			fileinfo = FileInfo.getfileInfobyuserIDandfilename(usrid, fileName);
		} catch (Exception e) {
			// TODO 自动生成\00\00 catch \00\00
			e.printStackTrace();
			try {
				orderinfo.mainInput.close();
			} catch (IOException e1) {
				// TODO 自动生成\00\00 catch \00\00
				e1.printStackTrace();
			}
			return ErrorCode.DATABASEERR;
		}
		if(fileinfo==null)
		{
			FileInfo.insertnewfileinfo(usrid, fileName, FileStatus.waitupload);
			try {
				fileinfo = FileInfo.getfileInfobyuserIDandfilename(usrid, fileName);
			} catch (Exception e) {
				// TODO 自动生成\00\00 catch \00\00
				e.printStackTrace();
				try {
					orderinfo.mainInput.close();
				} catch (IOException e1) {
					// TODO 自动生成\00\00 catch \00\00
					e1.printStackTrace();
				}
				return ErrorCode.DATABASEERR;
			}
		}
		else
		{
			if(fileinfo.getstatus()!=FileStatus.waitupload)
			{
				try {
					orderinfo.mainInput.close();
				} catch (IOException e) {
					// TODO 自动生成\00\00 catch \00\00
					e.printStackTrace();
				}
				return ErrorCode.CANTUPLOAD;
			}
		}
		
		fileinfo.setstatus(FileStatus.uploading);
		fileinfo.updatefilelist();
		
		//--------------------------------------------------------------------create temp file
		String tmppath = SysInfo.upTempPath+"/"+usrid;
		String tmpname = "/"+UUID.randomUUID();
		File tmpfile = new File(tmppath+tmpname);
		File tmppathfile = new File(tmppath);
		if((!tmppathfile.exists())&&(!tmppathfile.isDirectory()))
		{
			tmppathfile.mkdirs();
		}
		while(true)
		{
			if(tmpfile.exists())
			{
				tmpname="/"+UUID.randomUUID();
				tmpfile = new File(tmppath+tmpname);
			}
			else
			{
				try {
					tmpfile.createNewFile();
				} catch (IOException e) {
					// TODO 自动生成\00\00 catch \00\00
					e.printStackTrace();
					fileinfo.setstatus(FileStatus.uploaderr);
					fileinfo.updatefilelist();
					return ErrorCode.IOEXC;
				}
				break;
			}
		}
		FileOutputStream tmpout=null;
		try {
			 tmpout = new FileOutputStream(tmpfile);
		} catch (FileNotFoundException e) {
			// TODO 自动生成\00\00 catch \00\00
			e.printStackTrace();
			fileinfo.setstatus(FileStatus.uploaderr);
			fileinfo.updatefilelist();
			return ErrorCode.UNKNOWN;
		}
		
		//--------------------------------------------------------------------recieve file data
		errcode = dg.getData(new DataInputStream(orderinfo.mainInput), tmpout);
		try {
			tmpout.flush();
			tmpout.close();
		} catch (IOException e1) {
			// TODO 自动生成\00\00 catch \00\00
			e1.printStackTrace();
		}
		if(errcode!=ErrorCode.NORMAL)
		{
			try {
				orderinfo.mainInput.close();
			} catch (IOException e) {
				// TODO 自动生成\00\00 catch \00\00
				e.printStackTrace();
			}
			fileinfo.setstatus(FileStatus.uploaderr);
			fileinfo.updatefilelist();
			return errcode;
		}
		
		//--------------------------------------------------------------------splite
		fileinfo.setstatus(FileStatus.spliting);
		fileinfo.updatefilelist();
		geotiffTreater gtt = new geotiffTreater();
		GridCoverage2D sourcecov;
		try {
			sourcecov = geotiffTreater.read(tmppath+tmpname);
		} catch (Exception e) {
			// TODO 自动生成\00\00 catch \00\00
			e.printStackTrace();
			fileinfo.setstatus(FileStatus.uploaderr);
			fileinfo.updatefilelist();
			return ErrorCode.UNKNOWN;
		}
		String crswkt = sourcecov.getCoordinateReferenceSystem().toWKT();
		fileinfo.setCRS_decode(crswkt);
		Envelope env = sourcecov.getEnvelope();
		fileinfo.setenv_min_x(env.getMinimum(0));
		fileinfo.setenv_min_y(env.getMinimum(1));
		fileinfo.setenv_max_x(env.getMaximum(0));
		fileinfo.setenv_max_y(env.getMaximum(1));
		RenderedImage ri = sourcecov.getRenderedImage();
		fileinfo.setpixelsize_x(ri.getWidth());
		fileinfo.setpixelsize_y(ri.getHeight());
		ArrayList<HdpRenderedImageWritable> hriwList = gtt.split(ri, SysInfo.splitpixelsize, SysInfo.residule,fileName);
		
		//--------------------------------------------------------------------save to hdfs
		int maxRow=0;		//max row number
		int maxLine=0;		//max line number
		int splitCount = hriwList.size();
		//get path in hdfs
		HdfsMA ma = new HdfsMA();
		String hdfspath = "/"+usrid+"/"+fileName;
		try {
			if(ma.isExist(hdfspath))ma.delete(hdfspath);
			ma.mkdirs(hdfspath);
			String postfix;
			//save
			HdpRenderedImageWritable tmphri = new HdpRenderedImageWritable();
			int row=0;
			int line=0;
			for(int i=0;i<splitCount;i++)
			{
				tmphri = hriwList.get(splitCount-i-1);
				row=tmphri.number_x;
				line=tmphri.number_y;
				if(row>maxRow)maxRow=row;
				if(line>maxLine)maxLine=line;
				postfix=new String("_"+row+"_"+line+".seq");
				ma.saveSeqFile(hdfspath+"/"+fileName+postfix, new Text(fileName), tmphri);
			}
		} catch (IOException e) {
			// TODO 自动生成\00\00 catch \00\00
			e.printStackTrace();
			fileinfo.setstatus(FileStatus.uploaderr);
			fileinfo.updatefilelist();
			return ErrorCode.FROMHDFS;
		}
		fileinfo.setsplit_num_x(maxRow+1);
		fileinfo.setsplit_num_y(maxLine+1);
		fileinfo.setsplit_size(SysInfo.splitpixelsize);
		fileinfo.setstatus(FileStatus.normal);
		fileinfo.setresidule(SysInfo.residule);
		fileinfo.updatefilelist();
		
		
		
		tmpfile.delete();
		//--------------------------------------------------------------------return sucessful to user
		DataOutputStream dos = new DataOutputStream(orderinfo.mainOutput);
		try {
			dos.writeLong(1);
		} catch (IOException e) {
			// TODO 自动生成\00\00 catch \00\00
			e.printStackTrace();
		}
		
		return ErrorCode.NORMAL;
	}
	
}